![]() |
![]() |
|
Wie Sie sehen können, geben viele Methoden ein Stream-Objekt zurück. Das hat seinen Grund, denn mit einer geöffneten Datei will man arbeiten, sei es um den Inhalt zu lesen oder etwas in die Datei zu schreiben. Diese Operationen setzen aber einen Stream voraus, was das .NET Framework durch die Definition verschiedener Stream-Klassen abdeckt. Ein FileStream beschreibt dabei einfache Bytesequenzen, ein StreamReader basiert auf einer Textdatei. Einige typische Dateioperationen wollen wir uns nun im Detail ansehen. Kopieren einer DateiDem Kopieren einer Datei dient die Methode Copy, die einfach überladen ist:
Beide Versionen erwarten als erstes Argument die Übergabe des Dateinamens der zu kopierenden Datei. Befindet sich die zu kopierende Datei in keinem bekannten Suchpfad, muss der gesamte Zugriffspfad beschrieben werden. Im zweiten Argument müssen Sie das Zielverzeichnis und den Namen der Dateikopie angeben. Den Namen der kopierten Datei dürfen Sie gemäß den systemspezifischen Richtlinien festlegen, er muss nicht mit dem Ursprungsnamen der Datei übereinstimmen. Versucht man, ein Ziel anzugeben, in dem bereits eine gleichnamige Datei existiert, wird die Ausnahme DirectoryNotFoundException ausgelöst.
Sie können die Methode Copy auch einsetzen, wenn im Zielverzeichnis bereits eine Datei existiert, die denselben Namen hat wie die Datei, die Sie im zweiten Argument angeben. Dann müssen Sie die Überladung von Copy benutzen, die im dritten Parameter einen booleschen Wert erwartet. Übergeben Sie hier true, wird keine Ausnahme ausgelöst und die bereits vorhandene Datei durch den Inhalt der im ersten Argument übergebenen Datei überschrieben. Im folgenden Beispiel wird der Anwender dazu aufgefordert, den Pfad und das Zielverzeichnis der zu kopierenden Datei einzugeben. Dabei könnte es zu verschiedenen Ausnahmen kommen, beispielsweise wenn die zu kopierende Datei nicht gefunden wird oder der Anwender das Quell- oder Zielverzeichnis an der Konsole nicht angibt. Diese Fehler werden im Code aufgefangen und behandelt. Damit auch möglicherweise unberücksichtigte Fehler nicht zum vorzeitigen Ende der Laufzeit der Anwendung führen, wird im letzten catch-Block jede weitere Ausnahme, die im Zusammenhang mit den IO-Operationen steht, behandelt.
Als Pfad ist neben der absoluten Angabe, die auch Suchpfade einschließt, eine relative Angabe zulässig. Relative Pfadangaben beziehen sich dabei auf das aktuelle Arbeitsverzeichnis, in dem sich die ausführbare Datei der Anwendung befindet. Normalerweise werden Sie als Entwickler nicht wissen, in welchem Pfad der Anwender das Programm installiert hat. Um die Zeichenfolge darauf zu erhalten, können Sie sich diese mit
besorgen. Anschließend wird noch der Dateiname angehängt, bei dem es zu berücksichtigen gilt, dass GetCurrentDirectory nicht mit einem Backslash (\) abschließt.
Löschen einer DateiDie Syntax der Methode Delete zum Löschen einer Datei lautet wie folgt:
Der Parameter path erwartet entweder die absolute oder die relative Pfadangabe. Ungültige Angaben können auch hier unterschiedliche Ausnahmen auslösen.
Verschieben einer DateiDie Syntax der Methode Move zum Verschieben einer Datei ähnelt der der Methode Copy:
Dem ersten Parameter wird die zu verschiebende Datei übergeben, dem zweiten der neue Pfad der Datei. Mit Move lassen sich Dateien nicht nur aus einem Quell- in ein spezifiziertes Zielverzeichnis verschieben, denn die Methode kann auch zum Umbenennen von Dateinamen benutzt werden. Eine spezielle Methode dafür wird von der Klasse File nicht angeboten.
Prüfen, ob eine Datei existiertBeabsichtigen Sie, eine bestimmte Datei zu öffnen, stellt sich zunächst die Frage, ob eine Datei dieses Namens in dem angegebenen Pfad tatsächlich existiert. Die Klasse File veröffentlicht zur Beantwortung die Methode Exists, die den booleschen Wert false zurückliefert, wenn die Datei nicht gefunden wird.
Eine ähnliche Codesequenz dürfte in jedem Programm sinnvoll sein, in dem eine Operation die Existenz einer Datei zwingend voraussetzt. Das erspart die Codierung einer Ausnahmebehandlung. Öffnen einer DateiBevor Sie den Inhalt einer Datei lesen bzw. ändern können, muss diese geöffnet werden. Eine Datei zu öffnen, sagt aber noch nichts darüber aus, was ein Benutzer mit dieser Datei anfangen darf – ob er sie nur lesen kann oder auch das Recht besitzt, sie zu editieren. Auch das Verhalten bei mehreren gleichzeitigen Zugriffen ist ein Punkt, dem unter bestimmten Umständen Beachtung geschenkt werden muss. Die Klasse File stellt insgesamt vier Methoden zur Verfügung, die das Öffnen einer Datei bewirken: OpenRead, OpenText, OpenWrite sowie die mehrfach überladene Methode Open. Widmen wir unsere Aufmerksamkeit zuerst der letztgenannten.
Dem Parameter path wird beim Aufruf die Pfadangabe als Zeichenfolge mitgeteilt, bestehend aus Pfad und Dateiname. Für das Öffnen einer Datei ist das Betriebssystem zuständig, das wissen muss, wie es die Datei öffnen soll. Der mode-Parameter vom Typ FileMode steuert dieses Verhalten. Dabei handelt es sich um eine im Namespace System.IO definierte Enumeration, die insgesamt sechs Konstanten definiert (siehe Tabelle 12.2).
Der mode-Parameter beschreibt das Verhalten des Betriebssystems beim Öffnen einer Datei, jedoch nicht, was mit dem Inhalt der Datei geschehen soll. Soll er nur gelesen werden, oder möchte der Anwender in die Datei schreiben? Vielleicht sind auch beide Operationen gleichzeitig gewünscht. Diese Festlegung wird im Parameter access getroffen, der ebenfalls auf einer Aufzählung basiert – FileAccess. Diese hat nur drei Mitglieder: Read, Write und ReadWrite.
Eine Datei, die mit FileAccess.Read geöffnet wird, ist schreibgeschützt. Eine lesegeschützte Datei, deren Inhalt verändert werden soll, wird mit FileAccess.Write geöffnet. Die dritte Konstante FileAccess.ReadWrite beschreibt sowohl einen lesenden als auch schreibenden Zugriff. Versuchen Sie, auf eine mit FileAccess.Write geöffnete Datei lesend zuzugreifen, wird die Exception NotSupportedException ausgelöst. Lassen Sie sich durch diese unglückliche Namensgebung nicht irritieren, und kommen Sie nicht auf den Gedanken, es handele sich um einen Fehler, der nicht unterstützt wird (je nach Betonung des Namens könnte man sehr schnell zu dieser Annahme gelangen). Diese Exception beschreibt nur eine Operation, die auf eine geöffnete Datei ausgeführt, jedoch aufgrund des Öffnungsmodus nicht unterstützt wird (besser wäre hier wohl der Name NotSupportedFileAccessException gewesen). Kommen wir nun zum letzten Parameter der Open-Methode – share. Die Zeiten der unabhängigen lokalen Rechner neigt sich schon seit langem dem Ende zu, Netzwerke sind in den Unternehmen allgemeiner Standard. Infolgedessen muss der Umstand Berücksichtigung finden, dem man bis vor einigen Jahren meist keine besondere Beachtung geschenkt hat: Mehrere Anwendungen oder mehrere Threads versuchen, gleichzeitig auf dieselbe Datei zuzugreifen. share beschreibt das Verhalten der Datei, wenn nach dem ersten Öffnen weitere Zugriffe auf die Datei erfolgen. Wie schon von den beiden vorher besprochenen Parametern bekannt, wird auch dieser durch Konstanten beschrieben, die einer Enumeration des Namespace System.IO zugerechnet werden – FileShare. Die Mitglieder ähneln denen der Enumeration FileAccess, werden aber um ein weiteres ergänzt (genau genommen sind es zwei, aber der zweite spielt für uns keine Rolle).
Damit haben wir die Parameterliste der Methode Open abgehandelt, Ihnen stehen alle Hilfsmittel zur Verfügung, eine beliebige Datei unter bestimmten Voraussetzungen zu öffnen. Führen Sie sich aber vor Augen, dass eine geöffnete Datei nicht automatisch ihre Dateninformationen liefert oder sich manipulieren lässt. Diese Operationen haben mit dem Vorgang des Öffnens noch nichts zu tun, setzen ihn aber voraus. Beachten Sie in diesem Zusammenhang, dass Operationen, die den Inhalt einer Datei beeinflussen, auf dem zurückgegebenen Objekt vom Typ FileStream ausgeführt werden. In der folgenden Codezeile wird exemplarisch eine Datei mit Open geöffnet:
Die Parameter besagen, dass die Datei MyTestfile.txt im Stammverzeichnis C:\ geöffnet werden soll – falls es dort eine solche gibt. Wenn nicht, wird sie neu erzeugt. Der Inhalt der Datei lässt sich nach dem Öffnen sowohl lesen als auch ändern. Gleichzeitig werden weitere Zugriffe auf die Datei strikt unterbunden. Weitere Methoden zum Öffnen einer DateiFile.Open ist die allgemeinste Variante, eine Datei zu öffnen. Die Klasse File bietet aber drei weitere, spezialisiertere Formen an:
Mit OpenRead wird die angegebene Datei zum Lesen geöffnet, mit OpenWrite zum Schreiben. Diese beiden Methoden können, wie auch die Open-Methode, Dateien beliebigen Inhalts öffnen. OpenText hingegen ist auf Textdateien spezialisiert. Der Rückgabetyp der Methode OpenText ist ein StreamReader. Damit unterscheidet sich diese Methode von den anderen, welche die Referenz auf ein FileStream-Objekt liefern. Wir wollen uns an dieser Stelle noch nicht mit den Details dieser beiden Klassen beschäftigen – das folgt später in diesem Kapitel. Dennoch sollten Sie schon den Unterschied zwischen diesen beiden Streams kennen. Ein Objekt vom Typ StreamReader liest einzelne Zeichen (char) oder Zeichenfolgen aus einem Stream. Anders formuliert: Diese Klasse eignet sich für Textdateien. Im Gegensatz dazu wird der Datenstrom eines FileStream-Objekts byteweise gelesen. Die Interpretation dessen, was der Datenstrom beinhaltet, steht auf einem anderen Blatt. Es kann sich dabei natürlich auch um ASCII-Zeichen handeln, möglicherweise müssen die empfangenen Bytes aber auch als int oder float interpretiert werden. Kommen wir zurück zu den vier Methoden zum Öffnen von Dateien. Open, OpenRead und OpenWrite liefern eine Referenz auf ein FileStream-Objekt, sind in dieser Hinsicht also gleichwertig. Sie kommen dann zum Einsatz, wenn der Datenstrom Byte für Byte empfangen werden muss. Was ankommt, bedarf einer »Nachbearbeitung«, ansonsten können die Informationen nicht ausgewertet werden. Open ist die allgemeinste Variante, OpenRead und OpenWrite stellen insofern nur eine Teilmenge der Möglichkeiten von Open dar. Die vierte Methode, OpenText, ist eine spezialisierte Variante und nur für Textdateien geeignet. Dem wollen wir uns im folgendem Abschnitt widmen. Öffnen einer TextdateiIm folgenden Beispiel soll eine Textdatei geöffnet und der Inhalt an der Konsole ausgeben werden. Dazu wird im Code OpenText aufgerufen und die zurückgelieferte Referenz einer Objektvariablen des Typs StreamReader zugewiesen. Die Operationen, die im Zusammenhang mit dieser Klasse stehen, sollen uns an dieser Stelle noch nicht weiter interessieren.
Nach dem Start des Programms wird der Anwender an der Konsole zur Eingabe der Pfadangabe zu einer existierenden Textdatei aufgefordert. Nach der Bestätigung der Eingabe wird zuerst mit File.Exists geprüft, ob die Datei im spezifizierten Pfad überhaupt vorhanden ist. Gibt es die Datei nicht, erscheint eine entsprechende Meldung an der Konsole, und das Programm wird geschlossen. Existiert die Datei, wird sie mit File.OpenText geöffnet. In einer Schleife wird die Datei zeilenweise mit der Methode ReadLine des StreamReader-Objekts bis zum Dateiende eingelesen. Danach wird die Schleife beendet. Der einfachste Weg, in eine Datei zu schreiben und daraus zu lesenDer Weg, um in eine Datei zu schreiben oder eine Datei zu lesen, bedurfte bisher immer mehrerer Codezeilen. Eigentlich viel zu viel Aufwand, um eben schnell eine einfache Dateioperation auszuführen. Das .NET Framework wartet mit einer kaum vollständig zu beschreibenden Vielzahl an Möglichkeiten, die uns das Leben als Entwickler vereinfachen sollen. Die Verbesserungen betreffen auch die Klasse File, die im Vergleich mit .NET Framework 1.0/1.1 um mehrere Methoden ergänzt wurde, um mit nur einer einzigen Zeile Code Daten in eine Datei zu schreiben beziehungsweise mit einer Zeile Code Daten einzulesen. Es handelt sich hier um die Methoden ReadAllBytes, ReadAllLines und ReadAlltext zum Lesen und WriteAllBytes, WriteAllLines und WriteAllText zum schreiben. Mit der simplen Anweisung
können Sie bereits den Inhalt der Variablen strText in die angegebene Datei schreiben. Existiert die Datei schon, wird sie einfach überschrieben. Genauso einfach ist auch die inhaltliche Auswertung der Datei:
12.2.2 Die Klasse »FileInfo«
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FileInfo myFile = new FileInfo(@"C:\TestDir\Testfile.txt"); |
Der Konstruktor prüft nicht, ob die Datei tatsächlich existiert. Bevor Sie Operationen auf das Objekt ausführen, sollten Sie deshalb in jedem Fall vorher mit Exists sicherstellen, dass die Datei existiert.
| if (! myFile.Exists) { |
| // Datei existiert nicht |
| } |
Während Exists in der Klasse File als Methode implementiert ist, der die Pfadangabe beim Aufruf übergeben werden muss, handelt es sich in der Klasse FileInfo um eine schreibgeschützte Eigenschaft des FileInfo-Objekts.
Die Klasse FileInfo wird nicht direkt aus Object abgeleitet, sondern aus der Klasse FileSystemInfo. Sie erbt daher alle Mitglieder dieser Basisklasse, die gleichzeitig auch Basisklasse der Klasse DirectoryInfo ist, die wir weiter unten noch ansprechen.
FileInfo veröffentlicht eine Reihe von Instanzeigenschaften, denen der Zustand der Datei entnommen werden kann, die das FileInfo-Objekt beschreibt. So können Sie beispielsweise die Länge der Datei abfragen oder sich ein Objekt vom Typ Directory zurückgeben lassen (ein Directory-Objekt beschreibt ein Verzeichnis als Objekt, ähnlich wie FileInfo eine Datei).
| Eigenschaft | Beschreibung |
| Attributes | Ermöglicht das Setzen oder Auswerten der Dateiattribute (Hidden, Archive, ReadOnly usw.). |
| CreationTime | Liefert oder setzt das Erstellungsdatum der Datei. |
| Directory | Liefert eine Instanz des Verzeichnisses. |
| DirectoryName | Liefert eine Zeichenfolge mit der vollständigen Pfadangabe, jedoch ohne den Dateinamen. |
| Extension | Liefert die Dateierweiterung einschließlich des vorangestellten Punktes. |
| FullName | Gibt einen String mit der vollständigen Pfadangabe einschließlich des Dateinamens zurück. |
| LastAccessTime | Liefert oder setzt die Zeit des letzten Zugriffs auf die Datei. |
| LastWriteTime | Liefert oder setzt die Zeit des letzten schreibenden Zugriffs auf die Datei. |
| Length | Gibt die Länge der Datei zurück. |
| Name | Gibt den vollständigen Namen der Datei zurück. |
Wir wollen uns aus der Tabelle die Eigenschaft Attributes, die ihrerseits vom Typ FileAttributes ist, genauer ansehen. Attributes beschreibt ein Bitfeld bestimmter Größe. Jedes Attribut einer Datei wird durch Setzen eines bestimmten Bits in diesem Bitfeld beschrieben. Um festzustellen, ob ein Dateiattribut gesetzt ist, muss das alle Attribute beschreibende Bitfeld mit dem gesuchten Dateiattribut bitweise »&«-verknüpft werden. Weicht das Ergebnis von null ab, ist das Bit gesetzt.
Dazu ein Zahlenbeispiel. Nehmen wir an, das Attribut XYZ würde durch die Bitkombination 0000 1000 (= 8) beschrieben und das Bitfeld würde aktuell 0010 1001 (= 41) enthalten. Um zu prüfen, ob das Attribut XYZ durch das Bitfeld beschrieben wird, gilt:
| 0000 1000 |
| & 0010 1001 |
| -------------- |
| = 0000 1000 |
Das Ergebnis ist nicht null und so zu interpretieren, dass das Attribut im Bitfeld gesetzt ist.
Um aus einer Datei ein bestimmtes Attribut herauszufiltern, beispielsweise Hidden, müssten wir daher wie folgt vorgehen:
| FileInfo f = new FileInfo(@"C:\Testfile.txt"); |
| if (0 != (f.Attributes & FileAttributes.Hidden)) { |
| // Datei ist versteckt (hidden) |
| } |
Soll das Attribut gesetzt werden, bietet sich der »^«-Operator an:
| f.Attributes = f.Attributes ^ FileAttributes.Hidden; |
In gleicher Weise können Sie mit den Methoden GetAttributes und SetAttributes der Klasse File arbeiten.
Die Klassen File und FileInfo sind sich in den Funktionalitäten, die dem Entwickler angeboten werden, sehr ähnlich: Es lassen sich Dateien löschen, verschieben, umbenennen, kopieren, öffnen usw. Die meisten geben ein Stream-Objekt für weitergehende Operationen zurück.
| Methode | Rückgabetyp | Beschreibung |
| AppendText | StreamWriter | Hängt Text an eine existierende Datei an. |
| CopyTo | FileInfo | Kopiert die Datei an eine andere Speicherlokalität. |
| Create | FileStream | Erzeugt eine Datei. |
| CreateText | StreamWriter | Erzeugt eine neue Textdatei. |
| Delete | Löscht die Datei. | |
| Exists | Boolean | Gibt einen booleschen Wert zurück, der false ist, wenn die angegebene Datei nicht existiert. |
| MoveTo | Verschiebt die Datei in einen anderen Ordner oder benennt sie um. | |
| Open | FileStream | Öffnet eine Datei. |
| OpenRead | FileStream | Öffnet eine Datei zum Lesen. |
| OpenText | StreamReader | Öffnet eine Textdatei zum Lesen. |
| OpenWrite | FileStream | Öffnet eine Datei zum Schreiben. |
Die Klasse File veröffentlicht statische Methoden, um mit Dateien zu operieren, die Klasse FileInfo beschreibt die Referenz auf ein konkretes Dateiobjekt. Mit den Klassen Directory und DirectoryInfo wird dem auf Basis der Verzeichnisstruktur jeweils ein Gegenpart gegenübergestellt: Directory veröffentlicht nur Klassenmethoden, DirectoryInfo basiert auf einer konkreten Instanz. Es stellt sich natürlich sofort die Frage, warum die Architekten der Klassenbibliothek jeweils zwei Klassen mit nahezu gleichen Fähigkeiten vorgesehen haben.
Der entscheidende Unterschied liegt in der Art und Weise, wie die Klassen im Hintergrund arbeiten. Zugriffe auf das Dateisystem setzen immer operative Berechtigungen voraus. Verfügt der Anwender nicht über die entsprechenden Rechte, wird die angeforderte Aktion abgelehnt. Die beiden Klassen File und Directory prüfen das bei jedem Zugriff erneut und belasten so das System unnötig, während die Überprüfung von den Klassen DirectoryInfo und FileInfo nur einmal ausgeführt wird.
Mit Directory kann man Ordner anlegen, löschen oder verschieben, die in einem Verzeichnis physikalisch gespeicherte Dateinamen abrufen, verzeichnisspezifische Eigenschaften sowie das Erstellungsdatum oder das Datum des letzten Zugriffs ermitteln. Die folgende Tabelle 12.7 liefert einen unvollständigen Überblick über die Methoden von Directory.
| Methode | Beschreibung |
| CreateDirectory | Erzeugt ein Verzeichnis oder Unterverzeichnis. |
| Delete | Löscht ein Verzeichnis. |
| Exists | Überprüft, ob das angegebene Verzeichnis existiert. |
| GetCreationTime | Liefert das Erstellungsdatum samt Uhrzeit. |
| GetDirectories | Liefert die Namen aller Unterverzeichnisse eines spezifizierten Ordners. |
| GetFiles | Liefert alle Dateinamen eines spezifizierten Ordners zurück. |
| GetFileSystemEntries | Liefert die Namen aller Unterverzeichnisse und Dateien eines spezifizierten Ordners. |
| GetParent | Liefert den Namen des übergeordneten Verzeichnisses. |
| Move | Verschiebt ein Verzeichnis samt Dateien an eine neue Speicherlokalität. |
| SetCreationTime | Legt Datum und Uhrzeit eines Verzeichnisses fest. |
Die Fähigkeiten der Klasse DirectoryInfo ähneln denen von Directory, setzen jedoch ein konkretes Objekt für den Zugriff auf die Elementfunktionen voraus.
Im folgenden Beispiel werden einige Methoden und Eigenschaften der Klassen File, FileInfo und Directory benutzt. Das Programm fordert den Anwender dazu auf, an der Konsole ein beliebiges Verzeichnis anzugeben, dessen Unterverzeichnisse und Dateien ermittelt und unter der Angabe der Dateigröße und der Dateiattribute an der Konsole ausgegeben werden.
| // ------------------------------------------------------------ |
| // Beispiel: ...\Kapitel 12\FileDirectoryDemo |
| // ------------------------------------------------------------ |
| class Program { |
| public static void Main() { |
| DirectoryTest dirTest = new DirectoryTest(); |
| FileInfo myFile; |
| // Benutzereingabe anfordern |
| string path = dirTest.PathInput(); |
| int len = path.Length; |
| // alle Ordner und Dateien holen |
| string[] str = Directory.GetFileSystemEntries(path); |
| Console.WriteLine(); |
| Console.WriteLine("Ordner und Dateien im Verzeichnis {0}", path); |
| Console.WriteLine(new string('-', 80)); |
| for (int i = 0; i <= str.GetUpperBound(0); i++) { |
| // prüfen, ob der Eintrag ein Verzeichnis oder eine Datei ist |
| if(0 == (File.GetAttributes(str[i]) & FileAttributes.Directory)) { |
| // str(i) ist kein Verzeichnis |
| myFile = new FileInfo(str[i]); |
| string fileAttr = dirTest.GetFileAttributes(myFile); |
| Console.WriteLine("{0,-30}{1,25} kB {2,-10} ", |
| str[i].Substring(len – 1), |
| myFile.Length / 1024, |
| fileAttr); |
| } |
| else |
| Console.WriteLine("{0,-30}{1,-15}", str[i].Substring(len), "Dateiordner"); |
| } |
| Console.ReadLine(); |
| } |
| // Benutzer zur Eingabe eines Pfads auffordern |
| string PathInput() { |
| Console.Write("Geben Sie den zu durchsuchenden "); |
| Console.Write("Ordner an: "); |
| string searchPath = Console.ReadLine(); |
| // wenn die Benutzereingabe als letztes Zeichen kein'\' |
| // enthält, muss dieses angehängt werden |
| if(searchPath.Substring(searchPath.Length – 1) != "\\") |
| searchPath += "\\"; |
| return searchPath; |
| } |
| // Feststellung, welche Dateiattribute gesetzt sind |
| // Rückgabe eines Strings, der die gesetzten Attribute enthält |
| string GetFileAttributes(FileInfo strFile) { |
| string strAttr; |
| // prüfen, ob Archive-Attribut gesetzt ist |
| if(0 != (strFile.Attributes & FileAttributes.Archive)) |
| strAttr = "A "; |
| else |
| strAttr = " "; |
| // prüfen, ob Hidden-Attribut gesetzt ist |
| if(0 != (strFile.Attributes & FileAttributes.Hidden)) |
| strAttr += "H "; |
| else |
| strAttr += " "; |
| // prüfen, ob ReadOnly-Attribut gesetzt ist |
| if(0 != (strFile.Attributes & FileAttributes.ReadOnly)) |
| strAttr += "R "; |
| else |
| strAttr += " "; |
| // prüfen, ob System-Attribut gesetzt ist |
| if(0 != (strFile.Attributes & FileAttributes.System)) |
| strAttr += "S "; |
| else |
| strAttr += " "; |
| return strAttr; |
| } |
| } |
Starten Sie die Anwendung, könnte die Ausgabe an der Konsole ungefähr wie in der folgenden Abbildung dargestellt aussehen.

Hier klicken, um das Bild zu vergrößern
Abbildung 12.2 Ausgabe des Beispiels »FileDirectoryDemo«
Das gesamte Projekt ist in der Klasse DirectoryTest realisiert. Die Klasse enthält neben der statischen Methode Main die Methoden PathInput und GetAttributes. Die Methode PathInput liefert eine Zeichenfolge zurück, die den Pfad des Verzeichnisses enthält, dessen Inhalt abgefragt werden soll. Wichtig ist im Kontext des Beispiels, die Rückgabezeichenfolge mit einem Backslash abzuschließen, da ansonsten die spätere Ausgabe an der Konsole nicht immer gleich aussieht.
GetFileSystemEntries liefert als Ergebnis des Aufrufs ein String-Array, das dem Feld str zugewiesen wird.
| string str = Directory.GetFileSystemEntries(path); |
Jedes Element des Arrays kann sowohl eine Datei- als auch eine Verzeichnisangabe enthalten. Daher wird in einer for-Schleife das Array vom ersten bis zum letzten Element durchlaufen, um festzustellen, ob das Element eine Datei oder ein Verzeichnis beschreibt. Handelt es sich um ein Verzeichnis, ist das Attribut Directory gesetzt. Mit
| if(0 == (File.GetAttributes(str[i]) & FileAttributes.Directory)) |
wird das geprüft. Die Bedingung ist liefert true, wenn eine Datei vorliegt.
Nun folgt ein ganz entscheidender Punkt. Da das Programm die Größe der Datei ausgeben soll, können wir nicht mit File arbeiten, da in dieser Klasse keine Methode vorgesehen ist, die uns die Länge der Datei liefert. Dies ist nur über eine Instanz der Klasse FileInfo mit der Auswertung der schreibgeschützten Eigenschaft Length möglich, die bei jedem Schleifendurchlauf auf eine andere Datei verweist.
Die benutzerdefinierte Methode GetAttributes dient dazu, das übergebene FileInfo-Objekt auf die Attribute Hidden, ReadOnly, Archive und System hin zu untersuchen. Aus dem Ergebnis wird eine Zeichenfolge zusammengesetzt, die den Anforderungen der Anwendung entspricht. Zum Schluss erfolgt noch die formatierte Ausgabe an der Konsole. Für den Verzeichnis- bzw. Dateinamen ist eine maximale Breite von 30 Zeichen vorgesehen. Ist dieser Wert größer, ist das Ergebnis eine zwar etwas unansehnliche Ausgabe, aber unseren Ansprüchen soll sie genügen.
Eine Pfadangabe beschreibt die Lokalität einer Datei oder eines Verzeichnisses. Die Schreibweise der Pfadangabe wird vom Betriebssystem vorgegeben und ist nicht auf allen Plattformen zwangsläufig identisch. Bei manchen Systemen muss die Pfadangabe mit dem Laufwerksbuchstaben beginnen, bei anderen Systemen ist das nicht unbedingt vorgeschrieben. Pfadangaben können sich auch auf Dateien beziehen. Es gibt Systeme, die ermöglichen als Dateierweiterung zur Beschreibung des Dateityps maximal drei Buchstaben, während andere durchaus mehr zulassen.
Das sind nicht die einzigen Unterscheidungsmerkmale, die plattformspezifisch sind. Denken Sie nur an die Separatoren, mit denen zwei Verzeichnisse oder ein Verzeichnis von einer Datei getrennt werden. Windows-basierte Plattformen benutzen dazu das Zeichen Backslash (\), andere Systeme schreiben einen einfachen Slash (/) vor.
Die Klassen File und Directory greifen immer wieder auf Pfadangaben zurück. Da die Architektur der .NET-Plattform plattformneutral ist, muss dem Umstand der verschiedenen Vorschriften einer Pfadbeschreibung Rechnung getragen werden. Hieraus bezieht die nicht ableitbare Klasse Path ihre Existenzberechtigung, die Operationen auf Zeichenfolgen unterstützt, die Datei- oder Verzeichnisinformationen enthalten. Zudem werden auch Operationen angeboten, um einzelne Informationen aus der Pfadangabe herauszufiltern, und – was auch von großer Wichtigkeit sein kann – die Methoden von Path können benutzt werden, um den Pfad zum temporären Verzeichnis zu erhalten.
Alle Path-Klassenmitglieder sind statisch und haben die Aufgabe, eine Pfadangabe in einer bestimmten Weise zu filtern. Sie benötigen daher keine Instanz der Klasse Path, um auf ein Feld oder eine Methode dieser Klasse zugreifen zu können.
| Methode | Beschreibung |
| GetDirectoryName | Liefert aus einer gegebenen Pfadangabe das Verzeichnis zurück. |
| GetExtension | Liefert aus einer gegebenen Pfadangabe die Dateierweiterung einschließlich des führenden Punktes zurück. |
| GetFileName | Liefert den vollständigen Dateinamen zurück. |
| GetFileNameWithoutExtension | Liefert den Dateinamen ohne Dateierweiterung zurück. |
| GetFullPath | Liefert die komplette Pfadangabe zurück. |
| GetPathRoot | Liefert das Stammverzeichnis. |
Beachten Sie dabei, dass keine dieser Methoden testet, ob die Datei oder das Verzeichnis tatsächlich existiert. Es werden lediglich die Zeichenkette und die Vorschriften der spezifischen Plattform zur Bestimmung des Ergebnisses herangezogen.
Mit
| string strPath = @"C:\winnt\system\OLE2.dll" |
liefern die Methoden die folgenden Rückgaben:
| Console.WriteLine(Path.GetPathRoot(strPath)); |
| // liefert C:\ |
| Console.WriteLine(Path.GetDirectoryName(strPath)); |
| // liefert C:\winnt\system |
| Console.WriteLine(Path.GetFileNameWithoutExtension(strPath)); |
| // liefert OLE2 |
| Console.WriteLine(Path.GetFileName(strPath)); |
| // liefert OLE2.dll |
| Console.WriteLine(Path.GetFullPath(strPath)); |
| // liefert C:\winnt\system\OLE2.dll |
| Console.WriteLine(Path.GetExtension(strPath)); |
| // liefert .dll |
Sehr viele Anwendungen arbeiten mit Verzeichnissen, in die Dateien temporär, also nicht dauerhaft geschrieben werden. Die Klasse Path bietet mit GetTempPath eine Methode an, die das temporäre Verzeichnis des aktuell angemeldeten Benutzers liefert.
| public static string GetTempPath(); |
Unter Windows 2000/XP ist dieses Verzeichnis standardmäßig unter dem Namen Temp in
| C:\Dokumente und Einstellungen\Username\Lokale Einstellungen |
zu finden.
Mit GetTempFileName wird eine leere Datei im temporären Verzeichnis angelegt, der Rückgabewert ist die komplette Pfadangabe:
| public static string GetTempFileName(); |
Eine temporäre Datei kann von den anderen Methoden dazu benutzt werden, Zwischenergebnisse zu speichern, Informationen kurzfristig zu sichern und Abläufe zu protokollieren. Allerdings sollten Sie nicht vergessen, temporäre Dateien auch wieder zu löschen, wenn sie nicht mehr benötigt werden.
Sich mit .NET Framework 1.0/1.1 Laufwerksinformationen zu besorgen, war nicht ganz einfach. Eine speziell darauf zugeschnittene Klasse gab es nicht. So blieb keine andere Möglichkeit, als den Umweg über die Win32-API zu gehen, um sich die gewünschten oder erforderlichen Daten zu besorgen. In der aktuellen Version 2.0 wurde diese Lücke mit der neuen Klasse DriveInfo gefüllt.
Mit DriveInfo können Sie bestimmen, welche Laufwerke verfügbar sind und um welchen Typ von Laufwerk es sich dabei handelt. Zudem können Sie mit Hilfe einer Abfrage die Kapazität und den verfügbaren freien Speicherplatz auf dem Laufwerk ermitteln.
| Eigenschaft | Rückgabetyp | Beschreibung |
| AvailableFreeSpace | long | Gibt die Menge an verfügbarem freien Speicherplatz auf einem Laufwerk an. |
| DriveFormat | string | Ruft den Namen des Dateisystems ab. |
| DriveType | DriveType | Ruft den Laufwerktyp ab. |
| IsReady | bool | Der Rückgabewert gibt an, ob das Laufwerk bereit ist. |
| Name | string | Liefert den Namen des Laufwerks. |
| RootDirectory | DirectoryInfo | Liefert das Stammverzeichnis des Laufwerks. |
| TotalFreeSpace | long | Liefert den verfügbaren Speicherplatz. |
| TotalSize | long | Ruft die Gesamtgröße des Speicherplatzes auf einem Laufwerk ab. |
| VolumeLabel | string | Ruft die Datenträgerbezeichnung eines Laufwerks ab. |
Die Eigenschaft DriveType sollten wir uns noch etwas genauer ansehen. Sie liefert als Ergebnis des Aufrufs eine Konstante der gleichnamigen Enumeration ab. Diese hat insgesamt sieben Mitglieder, die Sie der folgenden Tabelle entnehmen können.
| Member | Beschreibung |
| CDRom | Optischer Datenträger (z.B. CD oder DVD) |
| Fixed | Festplatte |
| Network | Netzlaufwerk |
| NoRootDirectory | Das Laufwerk hat kein Stammverzeichnis. |
| Ram | RAM-Datenträger |
| Removable | Wechseldatenträger |
| Unknown | Unbekannter Laufwerkstyp |
Eine zweite neue Klasse, die dem Bereich Laufwerke, Ordner und Dateien zugeordnet werden kann, ist SpecialDirectories. Sie dient der Ermittlung Windows-spezifischer Pfade, zum Beispiel den zu »Eigene Bilder«. Die Angaben werden über statische Eigenschaften als Zeichenfolge geliefert.
| Eigenschaft | Beschreibung |
| AllUserApplicationData | Ruft einen Pfadnamen ab, der auf die Anwendungsdaten im Verzeichnis »\Dokumente und Einstellungen\All Users\Anwendungsdaten« zeigt. |
| CurrentUserApplicationData | Ruft einen Pfadnamen ab, der auf das Verzeichnis »Anwendungsdaten des aktuellen Benutzers« zeigt. |
| Desktop | Ruft den Pfad des »Desktop«-Verzeichnisses ab. |
| MyDocuments | Ruft den Pfad des »Eigene Dateien«-Verzeichnisses ab. |
| MyMusic | Ruft den Pfad des »Eigene Musik«-Verzeichnisses ab. |
| MyPictures | Ruft den Pfad des »Eigene Bilder«-Verzeichnisses ab. |
| ProgramFiles | Ruft den Pfad des »Program Files«-Verzeichnisses ab. |
| Programs | Ruft den Pfad des »Programme«-Verzeichnisses ab. |
| Temp | Ruft den Pfad des »Temp«-Verzeichnisses ab. |
Beabsichtigen Sie, diese Klasse einzusetzen, müssen Sie zuerst unter Verweise im Projektmappen-Explorer die Datei Microsoft.VisualBasic.dll einbinden. Zusätzlich sollten Sie auch den Namespace Microsoft.VisualBasic.FileIO bekannt geben. Weshalb die doch sehr interessante Klasse diesem Namespace zugeordnet worden ist, bleibt ein Geheimnis.
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.